<template>
  <BasicModal
    @register="registerModal"
    title="数据表处理"
    :width="1400"
    :destroyOnClose="true"
    v-bind="$attrs"
    @ok="handleSuccess"
  >
    <BasicTable @register="registerTable">
      <template #bodyCell="{ column, record }">
        <template v-if="column.dataIndex === 'status'">
          <span v-if="record.status === 1" class="text-blue-500">表结构相同</span>
          <span v-else-if="record.status === 2" class="text-orange-500">表结构不同</span>
          <span v-else-if="record.status === 3">数据库不存在该表，按新增处理</span>
        </template>
        <template v-if="column.dataIndex === 'operator'">
          <span v-if="record.status === 3">无需操作</span>
          <a-radio-group
            v-model:value="record.operator"
            name="radioGroup"
            @change="handleOperator(record)"
            v-else
          >
            <a-radio :value="1" v-if="record.status !== 2">沿用旧表</a-radio>
            <a-radio :value="2">创建新表（重新生成表名）</a-radio>
            <a-radio :value="3">
              覆盖旧表（
              <span class="text-red-500" v-if="record.status === 1">此操作会清空旧表数据</span>
              <span class="text-red-500" v-else>
                此操作会删除旧表，然后以相同表名按新结构进行生成
              </span>
              ）
            </a-radio>
          </a-radio-group>
        </template>
        <template v-if="column.dataIndex === 'newTableName'">
          <a-input
            v-if="record.operator === 2"
            v-model:value="record.newTableName"
            placeholder="请输入表名"
          />
        </template>
      </template>
    </BasicTable>
  </BasicModal>
</template>
<script lang="ts" setup>
  import { inject } from 'vue';
  import { BasicModal, useModalInner } from '/@/components/Modal';
  import { BasicTable, useTable, BasicColumn } from '/@/components/Table';
  import { GeneratorConfig } from '/@/model/generator/generatorConfig';
  import { validateTable, validateTableName } from '/@/api/system/generator';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { useI18n } from '/@/hooks/web/useI18n';

  const { notification } = useMessage();
  const { t } = useI18n();

  const emits = defineEmits(['success', 'register']);
  const generatorConfig = inject<GeneratorConfig>('generatorConfig');
  const columns: BasicColumn[] = [
    {
      title: '数据库名称',
      dataIndex: 'databaseName',
      width: 100,
      align: 'center',
    },
    {
      title: '数据表名',
      dataIndex: 'tableName',
      width: 120,
      align: 'center',
    },
    {
      title: '表结构配置比对结果',
      dataIndex: 'status',
      width: 120,
      align: 'center',
    },
    {
      title: '操作',
      dataIndex: 'operator',
      width: 400,
      align: 'center',
    },
    {
      title: '新表表名',
      dataIndex: 'newTableName',
      width: 80,
      align: 'center',
    },
  ];
  const [registerModal] = useModalInner();

  const [registerTable, { getDataSource }] = useTable({
    api: validateTable,
    beforeFetch: () => {
      return {
        databaseId: generatorConfig?.databaseId,
        tableStructureConfigs: generatorConfig?.tableStructureConfigs,
      };
    },
    afterFetch: (data) => {
      if (Array.isArray(data) && data.length) {
        data.map((item) => {
          const operator = item.status === 3 ? 4 : item.status === 2 ? 2 : 1;
          item.operator = operator;
          item.newTableName = '';
        });
      }
    },
    columns,
    striped: false,
    pagination: false,
    showIndexColumn: false,
  });

  const handleOperator = (record) => {
    if (record.operator !== 2) record.newTableName = '';
  };

  const handleSuccess = async () => {
    const newTableNameArr: string[] = [];
    const hasNoTableName = getDataSource().some((info) => {
      return info.operator === 2 && !info.newTableName;
    });
    if (hasNoTableName) {
      notification.error({
        message: t('提示'),
        description: '新表表名不能为空，否则无法创建数据表',
      });
      return;
    }
    getDataSource().map((item) => {
      if (item.operator === 2) {
        newTableNameArr.push(item.newTableName);
      }
    });
    const reg = /^[a-zA-Z0-9_]*$/;
    //判断表名是否符合要求
    const isTableNotSuccess = newTableNameArr?.some((tableName) => !reg.test(tableName));
    if (isTableNotSuccess) {
      notification.error({
        message: t('提示'),
        description: '表名只能包括字母、数字、下划线',
      });
      return;
    }
    await validateTableName({
      id: generatorConfig!.databaseId!,
      tableNames: newTableNameArr.toString(),
    });
    generatorConfig?.tableStructureConfigs?.forEach((item) => {
      getDataSource().forEach((data) => {
        if (item.tableName === data.tableName) {
          item.operator = data.operator;
          if (data.operator === 2) {
            item.tableName = data.newTableName;
            item.tableFieldConfigs.forEach((field) => {
              changeTableName(generatorConfig?.formJson.list, field.key, item.tableName, item.key);
            });
          }
        }
      });
    });
    emits('success');
  };

  const changeTableName = (list, fieldKey, tableName, tableKey) => {
    if (generatorConfig?.formJson.hiddenComponent?.length) {
      generatorConfig?.formJson.hiddenComponent?.map((component: any) => {
        if (component.key === fieldKey) {
          component.bindTable = tableName;
        }
      });
    }
    list?.map((component: any) => {
      if (component.type === 'form' || component.type === 'one-for-one') {
        if (component.key === tableKey) {
          component.bindTable = tableName;
        }
        if (component.children.length) {
          component.children.map((subComponent: any) => {
            if (subComponent.key === fieldKey) {
              subComponent.bindTable = tableName;
            }
          });
        }
      } else if (component.key === fieldKey) {
        component.bindTable = tableName;
      } else if (['tab', 'grid', 'card'].includes(component.type)) {
        for (const child of component.layout!) {
          changeTableName(child.list, fieldKey, tableName, tableKey);
        }
      }
    });
  };
</script>
<style lang="less" scoped>
  * {
    font-size: 12px;
  }
</style>
